package com.lightboat.web.controller.crm;

import cn.hutool.core.util.ObjUtil;
import com.alibaba.fastjson2.JSONArray;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.lightboat.common.annotation.Log;
import com.lightboat.common.constant.RedisConstants;
import com.lightboat.common.core.controller.BaseController;
import com.lightboat.common.core.domain.AjaxResult;
import com.lightboat.common.core.domain.bo.CrmProductBo;
import com.lightboat.common.core.page.TableDataInfo;
import com.lightboat.common.enums.BusinessType;
import com.lightboat.common.enums.OperationTypeEnum;
import com.lightboat.common.utils.PageUtils;
import com.lightboat.common.utils.RedisUtils;
import com.lightboat.common.utils.poi.ExcelUtil;
import com.lightboat.system.domain.CrmProduct;
import com.lightboat.system.domain.CrmProductStockRecord;
import com.lightboat.system.domain.request.AddPackageProductRequest;
import com.lightboat.system.mapper.CrmProductMapper;
import com.lightboat.system.service.ICrmProductService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 商品Controller
 *
 * @author lightboat
 * @date 2025-08-14
 */
@Tag(name = "商品管理")
@RestController
@RequiredArgsConstructor
@RequestMapping("/system/product")
public class CrmProductController extends BaseController {

    private final ICrmProductService crmProductService;
    private final CrmProductMapper crmProductMapper;

    /**
     * 查询商品列表
     */
    @Operation(summary = "查询商品列表")
    @PreAuthorize("@ss.hasPermi('system:product:list')")
    @GetMapping("/list")
    public TableDataInfo list(CrmProduct crmProduct) {
        PageUtils.<CrmProduct>chainOrderBy().orderByAsc(CrmProduct::getProductId).apply();
        startPage();
        List<CrmProduct> list = crmProductService.selectCrmProductList(crmProduct);
        clearPage();
        if (ObjUtil.isNotEmpty(list)){
            List<Long> allProductIds = list.stream()
                    .filter(f -> f.getExternalType() == 1 && ObjUtil.isNotEmpty(f.getProductCollection()))
                    .flatMap(m -> m.getProductCollection().stream())
                    .map(CrmProductBo::getProductId)
                    .distinct()  // 如果需要去重
                    .toList();

            if (ObjUtil.isNotEmpty(allProductIds)){
                List<CrmProduct> crmProducts = crmProductMapper.selectList(Wrappers.<CrmProduct>lambdaQuery().in(CrmProduct::getProductId, allProductIds));
                if (ObjUtil.isNotEmpty(crmProducts)) {
                    // 如果您想要确保键唯一性并处理可能的重复
                    Map<String, CrmProduct> productMap = crmProducts.stream()
                            .collect(Collectors.toMap(
                                    c -> c.getProductId().toString(),
                                    Function.identity(),  // 等同于 crmProduct -> crmProduct
                                    (existing, replacement) -> existing  // 保留现有的值
                            ));
                    list.stream().filter(f -> f.getExternalType() == 1 && ObjUtil.isNotEmpty(f.getProductCollection())).forEach(ls -> {
                        ls.getProductCollection().forEach(pc -> {
                            CrmProduct product = productMap.get(pc.getProductId().toString());
                            if (product != null) {
                                pc.setProductName(product.getProductName());
                                pc.setProductTitle(product.getProductTitle());
                                pc.setProductMultiTitle(product.getProductMultiTitle());
                                pc.setProductImage(product.getProductImage());
                                pc.setProductSpec(product.getProductSpec());
                                pc.setProductUnitNum(product.getProductUnitNum());
                                pc.setAttributeInfo(product.getAttributeInfo());
                                pc.setExternalType(product.getExternalType());
                                pc.setProductCategory(product.getProductCategory());
                                pc.setIsFixed(product.getIsFixed());
                                pc.setSalePrice(product.getSalePrice());
                                pc.setCostPrice(product.getCostPrice());
                                pc.setStock(product.getStock());
                            }
                        });
                    });
                }
             }
        }

        return getDataTable(list);
    }

    /**
     * 导出商品列表
     */
    @Operation(summary = "导出商品列表")
    @PreAuthorize("@ss.hasPermi('system:product:export')")
    @Log(title = "商品", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, CrmProduct crmProduct) {
        List<CrmProduct> list = crmProductService.selectCrmProductList(crmProduct);
        ExcelUtil<CrmProduct> util = new ExcelUtil<CrmProduct>(CrmProduct.class);
        util.exportExcel(response, list, "商品数据");
    }

    /**
     * 获取商品详细信息
     */
    @Operation(summary = "获取商品详细信息")
    @PreAuthorize("@ss.hasPermi('system:product:query')")
    @GetMapping(value = "/{productId}")
    public AjaxResult getInfo(@PathVariable("productId") Long productId) {
        return success(crmProductService.selectCrmProductByProductId(productId));
    }

    /**
     * 新增商品
     */
    @Operation(summary = "新增商品")
    @PreAuthorize("@ss.hasPermi('system:product:add')")
    @Log(title = "商品", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody CrmProduct crmProduct) {
        return toAjax(crmProductService.insertCrmProduct(crmProduct));
    }

    /**
     * 新增套餐
     */
    @Operation(summary = "新增套餐")
    @PreAuthorize("@ss.hasPermi('system:product:add')")
    @Log(title = "商品", businessType = BusinessType.INSERT)
    @PostMapping("package/add")
    public AjaxResult addPackage(@RequestBody AddPackageProductRequest request) {
        return toAjax(crmProductService.addPackage(request));
    }

    /**
     * 修改商品
     */
    @Operation(summary = "修改商品")
    @PreAuthorize("@ss.hasPermi('system:product:edit')")
    @Log(title = "商品", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody CrmProduct crmProduct) {
        crmProduct.setStock(null);
        return toAjax(crmProductService.updateCrmProduct(crmProduct));
    }

    /**
     * 追加商品库存
     */
    @Operation(summary = "追加商品库存")
    @PreAuthorize("@ss.hasPermi('system:product:edit')")
    @Log(title = "商品", businessType = BusinessType.UPDATE)
    @PostMapping("stock/add")
    public AjaxResult addStock(@RequestBody CrmProduct crmProduct) {
        CrmProductStockRecord crmProductStockRecord = new CrmProductStockRecord();
        crmProductStockRecord.setProductId(crmProduct.getProductId());
        crmProductStockRecord.setOrderStatus(2);
        crmProductStockRecord.setChangeQuantity(crmProduct.getStock());
        Boolean operation = crmProductService.stockOperation(crmProductStockRecord, OperationTypeEnum.ADD);
        return toAjax(operation);
    }
    /**
     * 删除商品
     */
    @Operation(summary = "删除商品")
    @PreAuthorize("@ss.hasPermi('system:product:remove')")
    @Log(title = "商品", businessType = BusinessType.DELETE)
    @DeleteMapping("/{productIds}")
    public AjaxResult remove(@PathVariable Long[] productIds) {
        return toAjax(crmProductService.deleteCrmProductByProductIds(productIds));
    }

    /**
     * 同步商品数据
     */
    @Operation(summary = "同步商品数据")
    @Log(title = "商品", businessType = BusinessType.IMPORT)
    @PreAuthorize("@ss.hasPermi('system:product:sync')")
    @PostMapping("/sync")
    // @Anonymous
    public AjaxResult sync(@RequestBody JSONArray json, @RequestHeader(name = "token") String token) {
        // if (!token.equals(Constants.INNER_TOKEN)) {
        //     return error("token错误");
        // }
        Map<String, Integer> result = RedisUtils.builder().redissonLock(RedisConstants.SYNC_PRODUCT_PREFIX + token, () -> crmProductService.syncCrmProduct(json), 3, 3, TimeUnit.SECONDS, "同步商品数据中...");
        return success(result);
    }

}
